package com.iamteer.day17;

import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
主要回顾：正则表达式

正则表达式对字符串的操作：

	1. 匹配: matches();
	
	2. 切割: split();
		在表达式 ((A)(B(C))) 中，存在四个这样的组：
		第1组：((A)(B(C)))
		第2组：(A)
		第3组：(B(C))
		第4组：(C)
		
		\1 表示引用第一组所匹配到的内容

	3. 替换: replaceAll();
		如果需要在正则外部引用组的内容，可以使用 "$组号"
		
	4. 查找: 
		4.1 Pattern 对象（正则对象）
		4.2 Matcher 对象（匹配器对象）
			4.2.1 find();	//通知匹配器去匹配字符串，查找符合规则的字符串。如果能找到则返回 true
			4.2.2 group();	//获取符合规则的子串
		
			典型的调用顺序是
			 Pattern p = Pattern.compile("a*b");
			 Matcher m = p.matcher("aaaaab");
			 boolean b = m.matches();		
------------------------------------------------------------------------------------------------
	预定义字符类（注意，没数量词的情况下，匹配一个字符）
		.	任何字符（与行结束符可能匹配也可能不匹配）
		\d	数字：[0-9]
		\D	非数字： [^0-9]
		\s	空白字符：[ \t\n\x0B\f\r]
		\S	非空白字符：[^\s]
		\w	单词字符：[a-zA-Z_0-9]
		\W	非单词字符：[^\w]
		
	Greedy 数量词
		X?	X，一次或一次也没有
		X*	X，零次或多次
		X+	X，一次或多次
		X{n}	X，恰好 n 次
		X{n,}	X，至少 n 次
		X{n,m}	X，至少 n 次，但是不超过 m 次
		
	字符类（注意，没数量词的情况下，匹配一个字符）
		[abc]	a、b 或 c（简单类）
		[^abc]	任何字符，除了 a、b 或 c（否定）
		[a-zA-Z]	a 到 z 或 A 到 Z，两头的字母包括在内（范围）
		[a-d[m-p]]	a 到 d 或 m 到 p：[a-dm-p]（并集）
		[a-z&&[def]]	d、e 或 f（交集）
		[a-z&&[^bc]]	a 到 z，除了 b 和 c：[ad-z]（减去）
		[a-z&&[^m-p]]	a 到 z，而非 m 到 p：[a-lq-z]（减去）
		
	边界匹配器
		^	行的开头
		$	行的结尾
		\b	单词边界：不匹配任何字符
		\B	非单词边界
		\A	输入的开头
		\G	上一个匹配的结尾
		\Z	输入的结尾，仅用于最后的结束符（如果有的话）
		\z	输入的结尾		
 */
public class RegularExp {

	public static void main(String[] args) {
//		String qq = "123456";
//		System.out.println(qq.matches("[1-9]\\d{4,10}") ? "合法 QQ" : "非法 QQ");
		
//		System.out.println("1".matches("."));
//		System.out.println("1".matches("\\d"));
//		System.out.println("1".matches("\\D"));
		
//		String phone = "18311892297";
//		matchPhone(phone);
		
//		String tel = "010-82902084";
//		matchTel(tel);
//		
//		testSplit();
		
//		testReplaceAll();
		
		testPattern();
	}
	
	//手机号规则：首位是 1，第二位 是 3 4 5 7 8，长度 11 位
	public static void matchPhone(String phone) {
		String regex = "1[34578]\\d{9}";
		System.out.println( phone + (phone.matches(regex) ? " 是手机号" : " 不是手机号"));
	}
	
	//电话号码规则：区号-主机号 区号：首位是 0，长度 3～4，主机号：首位不能是 0，长度 7～8
	public static void matchTel(String tel) {
		String regex = "0\\d{2,3}-[1-9]\\d{6,7}";
		System.out.println( tel + (tel.matches(regex) ? " 是电话号" : " 不是电话号"));
	}
	
	//切割方法
	public static void testSplit() {
		String  string = "明 天 放 假";
		String[] data = string.split(" +");		//根据空格切割
		System.out.println(Arrays.toString(data));
		
		string = "大家家家明天天天玩玩玩玩得开开心";
		//如果正则的内容需要被利用，那么需要对正则的内容进行分组。
		String[] data2 = string.split("(.)\\1+");
		System.out.println(Arrays.toString(data2));		
	}
	
	//替换方法
	public static void testReplaceAll() {
		String string = "如有需要请联系我：18311892297如有需要请联系我：18311892297如有需要请联系我：18311892297"
				+ "如有需要请联系我：18311892297如有需要请联系我：18311892297如有需要请联系我：18311892297";
		String regex = "1[34578]\\d{9}";
		string = string.replaceAll(regex, "****");
		System.out.println(string);
		
		string = "大大家家家明天天天玩玩玩玩得得开开心";
		regex = "(.)\\1+";
		string = string.replaceAll(regex, "$1");	//如果需要在正则外部引用组的内容，可以使用“$组号”
		System.out.println(string);
	}
	
	//查找方法
	public static void testPattern() {
		String string = "Hello world. I am Chuck. Java is a very difficult language";
		String regex = "\\b[a-zA-Z]{5}\\b";
		
		Pattern pattern = Pattern.compile(regex);	//1. 定义模式
		Matcher matcher = pattern.matcher(string);	//2. 进行匹配
		
		while (matcher.find()) {					//3. 查询匹配状态
			System.out.println(matcher.group());	//4. 获取结果
		}
	}
}
